package com.example.shiwu.util;

import static androidx.constraintlayout.motion.utils.Oscillator.TAG;

import android.os.Message;
import android.util.Log;

import com.example.shiwu.db.model.Device;
import com.example.shiwu.db.vo.MyQueue;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SocketInfoUtils {

    public Socket socket = null;
    private static InputStream mInputStream = null;
    private static OutputStream mOutStream = null;
    public OnMessageReceivedListener messageListener;
    public static int success_count = 0;
    public static int header_cou = 0;
    public static String receiveDataAll = "";
    private String cmd_index_len = "";//消息的id 10
    public static Integer packet_lens = 0;
    public static Integer packet_indx = 0;
    public static int packet_lens_old = 0;
    public static int packet_indx_old = 0;
    private Boolean isReConnect = false;
    public Boolean success8 = true;
    private Boolean readClears = true;
    private int port = 8080;

    public static SocketReceiveThread mReceiveThread;
    public static SocketInfoUtils instance;

    public static int receive_count = 0;
    public static String msg_0 = "";
    public static String msg_1 = "";
    //public byte[] buffer;
    private MyQueue queue;
    public ArrayList<String> msgArray;
    private DataParseUtil dataParseUtil;


    public SocketInfoUtils() {
        try {
            socket = new Socket(ContextVariable.IP, this.port);
            socket.setTcpNoDelay(true);
            socket.setSendBufferSize(32 * 1024);
            socket.setReceiveBufferSize(32 * 1024);
            socket.setSoLinger(true, 30);
            socket.setKeepAlive(true);
            Boolean sbl = socket.isConnected();

//            SocketAddress socAddress = new InetSocketAddress(ContextVariable.IP, this.port);
//            socket.connect(socAddress, 5000);
            //socket.setSoTimeout(3000);

            mInputStream = socket.getInputStream();
            mOutStream = socket.getOutputStream();
            if (mInputStream == null) {
                return;
            }
            queue = new MyQueue();
            msgArray = new ArrayList<>();
            dataParseUtil = new DataParseUtil();

            // 使用缓冲流进行数据传输
//            BufferedInputStream mInputStream = new BufferedInputStream(socket.getInputStream());
//            BufferedOutputStream mOutStream = new BufferedOutputStream(socket.getOutputStream());

            //success_count = 0;
            if (sbl) {
                //startListening();
                System.out.println("------------------socket 连接成功---------------");
            } else {
                System.out.println("------------------socket 连接失败---------------");
            }

            ;
        } catch (IOException e) {
            isReConnect = true;
            e.printStackTrace();
        }
    }

    public static synchronized SocketInfoUtils getInstance() {
        if (instance == null) {
            instance = new SocketInfoUtils();
        }
        return instance;
    }

//    public void setOnMessageReceivedListener(OnMessageReceivedListener listener) {
//        this.messageListener = listener;
//        startListening();
//    }

    public void startListening() {
        mReceiveThread = new SocketReceiveThread();
        mReceiveThread.start();
        writeMsg("22,M;");

        try {
            Thread.sleep(100);
            success_count = 0;
            writeMsg("22,M;");
            success_count = 1;
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    public void startListeningNew() {
        mReceiveThread = new SocketReceiveThread();
        mReceiveThread.start();

    }


    public static void writeMsg(String msg) {
        //Log.i(TAG, "writeMsg msg=" + msg);
        if (msg.length() == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg.getBytes());//发送
            mOutStream.flush();
            //Log.i(TAG, "-----------------writeMsg msg ="+ msg);
            //Log.i(TAG, "-----------------writeMsg msg ="+ msg+"   success_count====="+success_count);


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void writeMsgByte(byte[] msg) {

//        Log.i(TAG, "------------------------------------------------writeMsgByte msg=" + msg +"mReceiveThread.isAlive() ="+mReceiveThread.getState());
//        Log.i(TAG, "------------------------------------------------writeMsgByte msg mOutStream=" + mOutStream);
        if (msg.length == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg);//发送
            mOutStream.flush();
            mReceiveThread.resumeThread();
            //Log.i(TAG, "-----------------writeMsgByte msg ="+ new String(msg,"iso8859-1")+"   success_count====="+success_count);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void closeConnection() {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*释放资源*/
    public void releaseSocket() {

//        if (mReceiveThread != null) {
//            mReceiveThread.threadExit = true;
//            mReceiveThread = null;
//        }


        instance = null;

        if (mOutStream != null) {
            try {
                mOutStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            mOutStream = null;
        }
        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mInputStream = null;
        }

        if (socket != null) {
            try {
                socket.close();

            } catch (IOException e) {
            }
            socket = null;
        }

        /*重新初始化socket*/
        if (isReConnect) {
            socket = null;
            mInputStream = null;
            mOutStream = null;
//            new SocketUtils();
//            mReceiveThread = new SocketReceiveThread();
//            mReceiveThread.start();
        }
    }

    public synchronized void releaseSocketNew() {
        if (mReceiveThread != null) {
            mReceiveThread.threadExit = true;
            mReceiveThread = null;
        }
        instance = null;

        if (mOutStream != null) {
            try {
                mOutStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            mOutStream = null;
        }
        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mInputStream = null;
        }

        if (socket != null) {
            try {
                socket.close();

            } catch (IOException e) {
            }
            socket = null;
        }

        /*重新初始化socket*/
        if (isReConnect) {
            socket = null;
            mInputStream = null;
            mOutStream = null;
//            System.out.println("___________________mInputStream = null");
//            new SocketUtils();
//            mReceiveThread = new SocketReceiveThread();
//            mReceiveThread.start();
//            success_count = 6;
        }
    }


    public interface OnMessageReceivedListener {
        void onMessageReceived(byte message);

        void onMessageReceivedString(String message);

        void onConnectionLost();
    }

    public static void resumeThread() {
        mReceiveThread.resumeThread();
    }

    public static void pauseThread() {
        mReceiveThread.pauseThread();
    }


    class SocketReceiveThread extends Thread {
        public final Object lock = new Object();
        public boolean threadExit;


        public SocketReceiveThread() {
            threadExit = false;
        }

        /**
         * 调用这个方法实现暂停线程
         */
        public void pauseThread() {
            threadExit = true;
        }

        /**
         * 调用这个方法实现恢复线程的运行
         */
        public void resumeThread() {
            threadExit = false;
            synchronized (lock) {
                lock.notifyAll();
            }
        }

        public void threadExit() {
            threadExit = true;
        }

        /**
         * 注意：这个方法只能在run方法里调用，不然会阻塞主线程，导致页面无响应
         */
        public void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {

            while (threadExit == false) {
                try {
                    byte[] buffer = new byte[512];
                    //读取数据，返回值表示读到的数据长度。-1表示结束
                    int count = 0;
                    try {
                        if (mInputStream.available() > 0) {
                            count = mInputStream.read(buffer);
                            if (count == -1) {
                                Log.i(TAG, "read -1");
                                break;
                            } else {
                                //基于字符的读取或基于字节的读取
                                String receiveData = new String(buffer, 0, count);
                                Log.i(TAG, "==========read buffer:" + receiveData + ",count=" + count);
                                //Log.i(TAG, "==========read buffer1111:" + buffer );

                                String msgCode = receiveData.substring(2, receiveData.indexOf(";"));
                                Log.i(TAG, "==========read buffer msgCode:" + msgCode);
                                if (msgCode.contains("Success")) {
                                    success_count += 1;
                                    if (success_count == 2) {
                                        writeMsg("11,s;18,get;13,update;");

                                    }
                                    if (success_count > 2) {
//                                        byte[] b1 = new byte[512];
//                                        System.arraycopy(buffer, 10, b1, 0, buffer.length - 10);
//                                        System.out.println(b1);
//                                        int semicolon_inx = ByteUtil.bByteForSemicolon(b1,0);
//                                        String box_add = msgCode.substring(1,msgCode.length());
//                                        int semicolon_inx2 = ByteUtil.bByteForSemicolon(buffer,semicolon_inx);
//                                        byte[] byte_18 = ByteUtil.subByte(buffer, 0, semicolon_inx2);
//                                        byte[] byte_14 = ByteUtil.subByte(b1, semicolon_inx + 4, count - semicolon_inx - 4);
//                                        for (byte b : byte_14) {
//                                            queue.enQueue(b);
//                                        }
//                                        String msglis_18 = ByteUtil.byteTransformAscil(byte_18);
//                                        //System.out.println("  msglis_18 ===================="+ msglis_18);
//                                        String mas_18_val = msglis_18.split(",")[1];//固件版本
//
//                                        Double batt_vol = Double.valueOf(receive_one_field());//电源
//                                        System.out.println("  电源电压 ====================" + batt_vol);
//                                        String tx_high_vol1 = receive_one_field();//高压
//                                        String tx_high_vol ="";
//                                        if (tx_high_vol1.length() > 1) {
//                                            tx_high_vol = tx_high_vol1.substring(0, tx_high_vol1.indexOf(".")) + "V";//主机电压
//                                        }else {
//                                            tx_high_vol = tx_high_vol1 + "V";//温度
//                                        }
//
//                                        String temperature1 = receive_one_field();//温度
//                                        System.out.println("  温度 ====================" + temperature1);
//                                        String temperature = "";
//                                        if (temperature1.length() > 1) {
//                                            temperature = temperature1.substring(0, temperature1.indexOf(".")) + "°C";//温度
//                                        }else {
//                                            temperature = temperature1 + "°C";//温度
//                                        }
//
//                                        String humidity1 = receive_one_field();//湿度
//                                        String humidity = "";//湿度
//                                        if (humidity1.length() > 1) {
//                                            humidity = humidity1.substring(0, humidity1.indexOf(".")) + "°C";//湿度
//                                        }else {
//                                            humidity = humidity1+ "°C";
//                                        }
//
//                                        int batt_vol_int = batt_vol.intValue();
//                                        BigDecimal a = new BigDecimal(batt_vol_int);
//                                        BigDecimal b = new BigDecimal(ContextVariable.power_supply);
//                                        BigDecimal c = a.divide(b, 2, BigDecimal.ROUND_HALF_DOWN);
////                            System.out.println(c);
//                                        String batt_percent = String.valueOf(c.multiply(new BigDecimal(100)));
//                                        int batt_percent_val1 = Integer.parseInt(batt_percent.substring(0, batt_percent.indexOf(".")));
//                                        if(batt_percent_val1 >100){
//                                            batt_percent_val1 = 100;
//                                        }
//                                        String batt_percent_val = batt_percent_val1 + "%";
////                            System.out.println(batt_percent_val);
//                                        msgArray.add(mas_18_val);
//                                        msgArray.add(batt_percent_val);
//                                        msgArray.add(ContextVariable.channel);
//                                        msgArray.add(tx_high_vol);
//                                        msgArray.add(temperature);
//                                        msgArray.add(humidity);
//                                       // if (success_count == 2) {//发送到页面
//                                            success_count = 0;
//                                            queue.clear();
//                                            onPause();
//                                            releaseSocket();
//                                       // }
////                            Device device = new Device();
////                            device.setItemId(itemsId);
////                            device.setSn(mas_18_val);
////                            deviceService.saveOrUpdata(device);
                                    }
                                } else {
                                    int semicolon_inx = ByteUtil.bByteForSemicolon(buffer,0);
                                    String box_add = msgCode.substring(1,msgCode.length());
                                    int semicolon_inx2 = ByteUtil.bByteForSemicolon(buffer,semicolon_inx+1);
                                    byte[] byte_18 = ByteUtil.subByte(buffer, semicolon_inx+1, semicolon_inx2);
                                    byte[] byte_14 = ByteUtil.subByte(buffer, semicolon_inx2 + 4, count - semicolon_inx2 - 4);
                                    for (byte b : byte_14) {
                                        queue.enQueue(b);
                                    }
                                    String msglis_18 = ByteUtil.byteTransformAscil(byte_18);
                                    //System.out.println("  msglis_18 ===================="+ msglis_18);
                                    String mas_18_val = msglis_18.split(";")[0].replace("18, ","");//固件版本

                                    Double batt_vol = Double.valueOf(receive_one_field());//电源
                                    System.out.println("  电源电压 ====================" + batt_vol);
                                    String tx_high_vol1 = receive_one_field();//高压
                                    String tx_high_vol ="";
                                    if (tx_high_vol1.length() > 1) {
                                        tx_high_vol = tx_high_vol1.substring(0, tx_high_vol1.indexOf(".")) + "V";//主机电压
                                    }else {
                                        tx_high_vol = tx_high_vol1 + "V";//温度
                                    }
                                    String temperature1 = receive_one_field();//温度
                                    System.out.println("  温度 ====================" + temperature1);
                                    String temperature = "";
                                    if (temperature1.length() > 1) {
                                        temperature = temperature1.substring(0, temperature1.indexOf(".")) + "°C";//温度
                                    }else {
                                        temperature = temperature1 + "°C";//温度
                                    }
                                    String humidity1 = receive_one_field();//湿度

                                    String humidity = "";//湿度
                                    if (humidity1.length() > 1) {
                                        humidity = humidity1.substring(0, humidity1.indexOf(".")) + "°C";//湿度
                                    }else {
                                        humidity = humidity1+ "°C";
                                    }

//                                    int batt_vol_int = batt_vol.intValue();
//                                    BigDecimal a = new BigDecimal(batt_vol_int);
//                                    BigDecimal b = new BigDecimal(ContextVariable.power_supply);
//                                    BigDecimal c = a.divide(b, 2, BigDecimal.ROUND_HALF_DOWN);
//                                    String batt_percent = String.valueOf(c.multiply(new BigDecimal(100)));
                                    int batt_vol_int = Math.round(batt_vol.intValue());
                                    Double batt_vol_dou = (double) (batt_vol_int/ContextVariable.power_supply*100);
                                    String batt_percent = String.valueOf(batt_vol_dou);
                                    int batt_percent_val1 = Integer.parseInt(batt_percent.substring(0, batt_percent.indexOf(".")));
                                    if(batt_percent_val1 >100){
                                        batt_percent_val1 = 100;
                                    }
                                    String batt_percent_val = batt_percent_val1 + "%";
                                    msgArray.add(box_add);
                                    msgArray.add(mas_18_val);
                                    msgArray.add(batt_percent_val);
                                    msgArray.add(ContextVariable.channel);
                                    msgArray.add(tx_high_vol);
                                    msgArray.add(temperature);
                                    msgArray.add(humidity);
                                    if (success_count == 2) {//发送到页面
                                        success_count = 0;
                                        queue.clear();
                                        onPause();
                                        releaseSocket();
                                    }
                                }
                            }
                        }


                    } catch (Exception e) {
                        e.printStackTrace();
                        //messageListener.onMessageReceivedString("null");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            System.out.println("-------threadExit222222222222222222222222 == " + threadExit);
        }
    }

    private synchronized String receive_one_field() throws InterruptedException, UnsupportedEncodingException {
        Boolean escaped = false;
        Boolean command_sep_found = false;
        ArrayList<Byte> one_field = new ArrayList<Byte>();
        Boolean bl = true;
        String msgbt = "";
        while (bl) {

            byte tmp = (byte) queue.deQueue();
            if (escaped) {
                if (tmp == 44 || tmp == 59 || tmp == 47) {
                    one_field.add(tmp);
                    escaped = false;
                } else {
                    one_field.add(tmp);
                    escaped = false;
                }
            } else {
                if (tmp == 47) {
                    //遇到 / 就escaped = True 继续循环
                    escaped = true;
                } else if (tmp == 44) {
                    break;
                } else if (tmp == 59) {
                    command_sep_found = true;
                    break;
                } else {
                    one_field.add(tmp);
                }
            }

        }
        if (one_field.size() > 0) {
            //System.out.println("------one_field-------" + one_field);
            msgbt = recv_float(one_field);
        }

        return msgbt;
    }

    private String recv_float(ArrayList<Byte> val) {
        List<Byte> ab5 = dataParseUtil.objToByList(val);
        byte[] str_one_field5 = dataParseUtil.listTobyte(ab5);
        if (str_one_field5.length == 1) {
            return String.valueOf(str_one_field5[0]);
        }
        return dataParseUtil.recv_float(str_one_field5);
    }
}


